"""地图系统模块
处理区域切换、探索、随机事件等地图相关功能
"""
import random
from typing import Dict, List, Optional, Tuple
from .game_core import GameCore, Player, AreaInfo, GameEvent, Realm
from .battle_system import BattleSystem

class MapSystem:
    """地图系统类"""
    
    def __init__(self, game_core: GameCore):
        self.game_core = game_core
        self.battle_system = BattleSystem(game_core)
    
    def move_to_area(self, player: Player, target_area: str) -> Tuple[bool, str]:
        """移动到指定区域"""
        # 检查目标区域是否存在
        if target_area not in self.game_core.areas:
            return False, f"区域 {target_area} 不存在"
        
        # 检查是否是相邻区域
        current_area_info = self.game_core.areas.get(player.current_area)
        if current_area_info and target_area not in current_area_info.adjacent_areas:
            return False, f"无法从 {player.current_area} 直接到达 {target_area}"
        
        target_area_info = self.game_core.areas[target_area]
        
        # 检查境界要求
        if not player.can_enter_area(target_area_info.realm_requirement):
            return False, f"需要 {target_area_info.realm_requirement.name} 境界才能进入 {target_area}"
        
        # 检查解锁道具要求
        if target_area_info.unlock_item and not player.has_item(target_area_info.unlock_item):
            return False, f"需要 {target_area_info.unlock_item} 才能进入 {target_area}"
        
        # 检查区域是否已解锁
        if target_area not in player.unlocked_areas:
            # 如果满足所有条件，解锁区域
            player.unlocked_areas.append(target_area)
        
        # 移动到目标区域
        old_area = player.current_area
        player.current_area = target_area
        
        # 触发移动事件
        event_result = self._trigger_random_event(player, target_area_info.random_events)
        
        message = f"成功从 {old_area} 移动到 {target_area}"
        if event_result:
            message += f"\n{event_result}"
        
        return True, message
    
    def explore_area(self, player: Player) -> str:
        """探索当前区域"""
        current_area_info = self.game_core.areas.get(player.current_area)
        if not current_area_info:
            return "当前区域信息异常"
        
        # 首先检查是否遇到怪物
        encounter_chance = self.battle_system.get_encounter_chance(player.current_area)
        if random.random() < encounter_chance:
            # 遇到怪物，进入战斗
            monster = self.battle_system.get_random_monster(player.current_area)
            if monster:
                battle_result = self.battle_system.start_battle(player, monster)
                return battle_result.message
        
        # 没有遇到怪物，正常探索
        # 获取资源
        resource_result = self._get_random_resource(player, current_area_info.resources)
        
        # 触发随机事件
        event_result = self._trigger_random_event(player, current_area_info.random_events)
        
        # 获得少量经验
        exp_gain = random.randint(1, 5)
        player.exp += exp_gain
        
        message = f"在 {player.current_area} 探索了一番"
        if resource_result:
            message += f"\n{resource_result}"
        if event_result:
            message += f"\n{event_result}"
        message += f"\n获得了 {exp_gain} 点修为"
        
        return message
    
    def _get_random_resource(self, player: Player, resources: Dict[str, float]) -> Optional[str]:
        """随机获取资源"""
        if not resources:
            return None
        
        # 根据概率随机选择资源
        rand = random.random()
        cumulative_prob = 0
        
        for resource_name, probability in resources.items():
            cumulative_prob += probability
            if rand <= cumulative_prob:
                if resource_name == "空":
                    return "什么也没有找到"
                else:
                    # 随机数量（1-3个）
                    count = random.randint(1, 3)
                    player.add_item(resource_name, count)
                    return f"获得了 {resource_name} x{count}"
        
        return "什么也没有找到"
    
    def _trigger_random_event(self, player: Player, events: Dict[str, float]) -> Optional[str]:
        """触发随机事件"""
        if not events:
            return None
        
        # 根据概率随机选择事件
        rand = random.random()
        cumulative_prob = 0
        
        for event_name, probability in events.items():
            cumulative_prob += probability
            if rand <= cumulative_prob:
                return self._execute_event(player, event_name)
        
        return None
    
    def _execute_event(self, player: Player, event_name: str) -> str:
        """执行事件"""
        event = self.game_core.events.get(event_name)
        if not event:
            # 使用内置事件处理
            return self._trigger_event(player, event_name)
        
        result_message = f"事件触发: {event.description}"
        
        # 处理事件效果
        for effect_type, effect_value in event.effects.items():
            if effect_type == "exp":
                player.exp += effect_value
                result_message += f"\n获得 {effect_value} 点修为"
            elif effect_type == "item":
                player.add_item(effect_value, 1)
                result_message += f"\n获得物品: {effect_value}"
            elif effect_type == "hp":
                player.hp = min(player.max_hp, player.hp + effect_value)
                result_message += f"\n生命值 {'恢复' if effect_value > 0 else '减少'} {abs(effect_value)}"
            elif effect_type == "mp":
                player.mp = min(player.max_mp, player.mp + effect_value)
                result_message += f"\n法力值 {'恢复' if effect_value > 0 else '减少'} {abs(effect_value)}"
            elif effect_type == "message":
                result_message += f"\n{effect_value}"
            elif effect_type == "battle":
                result_message += f"\n进入战斗: {effect_value}"
                # 这里可以扩展战斗系统
        
        return result_message
    
    def _trigger_event(self, player: Player, event_name: str) -> str:
        """触发随机事件"""
        event_messages = {
            # 基础事件
            "镇守巡查": "遇到了镇守巡查，你恭敬行礼后继续前行。",
            "灵宠出现": "一只小灵兽出现在你面前，好奇地看着你。",
            "灵脉波动": "感受到灵脉的波动，你的修为略有精进。",
            "天道感应": "突然感受到天道的感应，这是修仙者的机缘！",
            
            # 战斗事件
            "灵蝶围攻": "一群灵蝶将你包围，它们似乎在保护什么...",
            "江湖恩怨": "遇到了江湖恩怨，两派弟子正在争斗。",
            "古塔守护": "古塔的守护灵现身，考验着进入者的资格。",
            "虚空风暴": "虚空中突然刮起风暴，空间开始扭曲！",
            "仙宫试炼": "仙宫的试炼开始了，考验你的道心和实力。",
            "混沌风暴": "混沌之力汇聚成风暴，威力惊人！",
            "九天神兽": "九天之上的神兽降临，散发着强大的威压。",
            "时光乱流": "时光乱流出现，过去与未来交织在一起。",
            
            # 社交事件
            "同道求助": "遇到了同道中人，他们请求你的帮助。",
            "武林大会": "正值武林大会召开，各路英雄齐聚一堂。",
            "仙市交易": "仙市中有修士在进行珍贵物品的交易。",
            "商贾纷争": "商贾之间发生了纷争，需要有人调解。",
            
            # 机关/探索事件
            "洞府机关": "触发了洞府中的古老机关，需要小心应对。",
            "上古幻象": "古塔中出现了上古时期的幻象。",
            "虚空生灵": "虚空中诞生了奇异的生灵。",
            "云霄异象": "云霄之上出现了异象，预示着什么。",
            "知识诅咒": "禁书散发出诅咒之力，考验着阅读者。",
            
            # 感悟事件
            "灵泉异象": "灵泉中出现异象，蕴含着深奥的道理。",
            "天机测算": "天机阁中的长老为你测算天机。",
            "命运指引": "感受到了命运的指引，前路更加清晰。",
            "古籍守护者": "古籍的守护者现身，传授古老的智慧。",
            "知识启发": "从古籍中获得了知识的启发。",
            "法则领悟": "在混沌中领悟到了天地法则的奥秘。",
            "云海奇遇": "在云海中遇到了奇异的际遇。",
            "真理启示": "获得了真理的启示，道心更加坚定。",
            "岁月重现": "时光殿中重现了过去的岁月。",
        }
        
        message = event_messages.get(event_name, f"触发了神秘事件：{event_name}")
        
        # 根据事件类型给予不同奖励
        if event_name in ["灵脉波动", "天道感应", "法则领悟"]:
            exp_gain = random.randint(5, 15)
            player.exp += exp_gain
            message += f" 获得{exp_gain}点修为！"
        elif event_name in ["同道求助", "知识启发", "真理启示"]:
            exp_gain = random.randint(10, 20)
            player.exp += exp_gain
            message += f" 获得{exp_gain}点修为！"
        elif event_name in ["灵宠出现"]:
            # 有概率获得物品
            if random.random() < 0.3:
                items = ["低阶灵石", "破损妖丹"]
                item = random.choice(items)
                player.add_item(item, 1)
                message += f" 获得了{item}！"
        
        return message
    
    def get_area_info(self, player: Player, area_name: str = None) -> str:
        """获取区域信息"""
        if area_name is None:
            area_name = player.current_area
        
        area_info = self.game_core.areas.get(area_name)
        if not area_info:
            return f"区域 {area_name} 不存在"
        
        info_lines = [
            f"区域: {area_name}",
            f"境界要求: {area_info.realm_requirement.name}",
        ]
        
        if area_info.unlock_item:
            info_lines.append(f"解锁道具: {area_info.unlock_item}")
        
        # 相邻区域
        adjacent_areas = []
        for adj_area in area_info.adjacent_areas:
            if adj_area in player.unlocked_areas:
                adjacent_areas.append(adj_area)
            else:
                adjacent_areas.append(f"{adj_area}(未解锁)")
        
        if adjacent_areas:
            info_lines.append(f"相邻区域: {', '.join(adjacent_areas)}")
        
        # 资源信息
        if area_info.resources:
            resources_info = []
            for resource, prob in area_info.resources.items():
                resources_info.append(f"{resource}({prob*100:.0f}%)")
            info_lines.append(f"可能获得: {', '.join(resources_info)}")
        
        # 事件信息
        if area_info.random_events:
            events_info = []
            for event, prob in area_info.random_events.items():
                events_info.append(f"{event}({prob*100:.0f}%)")
            info_lines.append(f"可能事件: {', '.join(events_info)}")
        
        return "\n".join(info_lines)
    
    def get_available_areas(self, player: Player) -> List[str]:
        """获取玩家可以前往的区域列表"""
        current_area_info = self.game_core.areas.get(player.current_area)
        if not current_area_info:
            return []
        
        available_areas = []
        for area_name in current_area_info.adjacent_areas:
            area_info = self.game_core.areas.get(area_name)
            if not area_info:
                continue
            
            # 检查境界要求
            if not player.can_enter_area(area_info.realm_requirement):
                continue
            
            # 检查解锁道具要求
            if area_info.unlock_item and not player.has_item(area_info.unlock_item):
                continue
            
            available_areas.append(area_name)
        
        return available_areas
    
    def get_map_overview(self, player: Player) -> str:
        """获取地图总览"""
        lines = ["=== 修仙世界地图 ==="]
        
        for area_name, area_info in self.game_core.areas.items():
            status = ""
            if area_name == player.current_area:
                status = " [当前位置]"
            elif area_name in player.unlocked_areas:
                status = " [已解锁]"
            else:
                status = " [未解锁]"
            
            lines.append(f"{area_name}{status} - 境界要求: {area_info.realm_requirement.name}")
        
        return "\n".join(lines)